﻿@inject IPeopleService peopleService
@inject IUserStatusService statusService
@inject ViewDataService ViewDataService
@inject IJSRuntime JsRuntime
@inject IImageCacheService imageCache
@inject IDialogService dialogService
@inject ClientUIStateService uiService

<div class="damselfly-persontile" style="@TileStyle">
    <div title="@Person.PersonGuid" class="damselfly-personimg" @onclick="PersonClicked">
        <img @key="@Person.PersonId" title="@PersonTitle" src="@FaceLink">
    </div>
    @if( processingUpdate )
    {
        <div class="damselfly-personfield">
            Updating name...
        </div>
    }
    else
    {
        <div class="damselfly-personfield">
            @if( Disabled )
            {
                @Name
            }
            else
            {
                <MudTextField @key="@Person.PersonId" @bind-Value="@Name" ReadOnly="false" Margin="Margin.Dense" 
                              Variant="UIConstants.MudVariant"/>
            }
        </div>
    }
</div>

@code {
    private string PersonTitle => $"{Person.Name}\nState: {Person.State}\nFace Data Sets: {Person.FaceData.Count}";
    private bool processingUpdate = false;

    [Parameter] public bool Disabled { get; set; }
    
    [Parameter] public bool Small { get; set; } = false;
    
    [Parameter] public Person Person { get; set; }

    [Parameter] public EventCallback PersonChanged { get; set; }
    
    [Parameter] public EventCallback<Person> OnPersonClicked { get; set; }

    public string Name
    {
        get => Person.Name;
        set => _ = UpdateName(value);
    }

    public string FaceLink => $"/face/{Person.PersonId}?nocache={Person.LastUpdated:yyyyMMddHHmmss}";
    public string TileStyle;

    private async Task PersonClicked()
    {
        await OnPersonClicked.InvokeAsync(Person);
    }
    
    private void GenerateImageStyle()
    {
        var fontSize = "13pt";
        var size = 180;
        if( uiService.IsSmallScreenDevice )
        {
            const int imageGap = 5;
            var targetImagesPerRow = uiService.IsPortraitDevice ? 4 : 6;

            size = int.Max( uiService.ScreenWidth / targetImagesPerRow - (targetImagesPerRow - 1) * imageGap, 50);
            fontSize = "9pt";
        }
        else if( Small )
        {
            size = 90;
            fontSize = "9pt";
        }

        TileStyle = $"max-width: {size}px; height: auto; max-height: {size+20}px;font-size: {fontSize};";
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();

        GenerateImageStyle();
    }

    private async Task UpdateName(string newName)
    {
        if( !string.IsNullOrEmpty(newName) && !newName.Equals(Person.Name) )
        {
            processingUpdate = true;
            StateHasChanged();

            var allNames = await peopleService.GetPeopleNames(newName);
            var canRename = true;
            var merge = false;

            // If the new name already exists for another person, then we're going to merge 
            // them together to form a single person. 
            if( allNames.Contains(newName, StringComparer.OrdinalIgnoreCase) )
            {
                canRename = false;

                var result = await dialogService.ShowMessageBox(
                    $"Merge with existing {newName}?",
                    $"A person with the name '{newName}' exists already. Would you like to merge the two?",
                    "Merge", cancelText: "Cancel");

                if( result != null && result.Value )
                {
                    canRename = true;
                    merge = true;
                }
            }

            _ = JsRuntime.InvokeAsync<string>("clearFocus");

            if( canRename )
            {
                var req = new NameChangeRequest { PersonId = Person.PersonId, NewName = newName, Merge = merge };
                await peopleService.UpdatePersonName(req);

                // Update the local copy
                Person.Name = newName;

                // Massive hammer to crack a small nut. We've changed the name of a person, and any 
                // number of imageObjects could be cached with the old name. So evict them all. 
                // Performance hit, of course, but better than showing stale names.
                await imageCache.ClearCache();

                await PersonChanged.InvokeAsync();
                processingUpdate = false;
                StateHasChanged();

                statusService.UpdateStatus($"Name set to '{newName}'");
            }
        }
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if( firstRender )
        {
            ViewDataService.SetSideBarState(new ViewDataService.SideBarState { ShowBasket = true, ShowFolderList = true });
        }
    }

}